package com.ytjj.qmyx.admin.service.data.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gexin.fastjson.JSON;
import com.ytjj.common.constants.DateUtils;
import com.ytjj.common.constants.RedisConstants;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.qqzengip.IpSearch;
import com.ytjj.qmyx.admin.constants.SysConfigConstants;
import com.ytjj.qmyx.admin.constants.data.MongoCollectionNameConstants;
import com.ytjj.qmyx.admin.dao.ChannelDao;
import com.ytjj.qmyx.admin.dao.OrderStatisticsMapper;
import com.ytjj.qmyx.admin.eunm.ActivityTypeNameCode;
import com.ytjj.qmyx.admin.model.request.UserStatisticsRequest;
import com.ytjj.qmyx.admin.model.Admin;
import com.ytjj.qmyx.admin.model.request.bankerProduct.NewStatisticsRequest;
import com.ytjj.qmyx.admin.model.request.dataStatistics.DataStatisticsRequest;
import com.ytjj.qmyx.admin.model.response.ProductDataResponse;
import com.ytjj.qmyx.admin.model.response.UserOrderAnalysisResponse;
import com.ytjj.qmyx.admin.model.response.statistics.AllNewStatisticsResponse;
import com.ytjj.qmyx.admin.model.response.statistics.NewOrderStatisticsResponse;
import com.ytjj.qmyx.admin.model.response.statistics.NewStatisticsResponse;
import com.ytjj.qmyx.admin.model.response.statistics.UserPayStatisticsResponse;
import com.ytjj.qmyx.admin.service.data.NewStatisticsService;
import com.ytjj.qmyx.admin.service.data.PlatformStatisticService;
import com.ytjj.qmyx.admin.utils.CalendarUtil;
import com.ytjj.qmyx.admin.utils.MD5Util;
import com.ytjj.qmyx.admin.utils.UserUtil;
import com.ytjj.qmyx.mall.mapper.ActivityColumnMapper;
import com.ytjj.qmyx.mall.mapper.ProductMapper;
import com.ytjj.qmyx.mall.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Case;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @ClassName NewStatisticsServiceImpl
 *
 * 
 * @Version 1.0
 **/
@Service
@Slf4j
public class NewStatisticsServiceImpl implements NewStatisticsService {
    @Resource
    private OrderStatisticsMapper orderStatisticsMapper;
    @Resource
    private ActivityColumnMapper activityColumnMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private RedisService redisService;
    @Resource
    private PlatformStatisticService platformStatisticService;
    @Autowired
    private ChannelDao channelDao;
    @Value("${adminIddyx:268}")
    private Integer adminIdjxy;
    /**
     * 地址库
     */
    @Value("${ip.sourcefile.path:}")
    private String ipSourceFilePath;

    private HashMap<Integer,String> getActivityColumnMap() {
        HashMap<Integer,String> activityColumnMap=new HashMap<>();
        ActivityColumnExample activityColumnExample = new ActivityColumnExample();
        activityColumnExample.setOrderByClause("sort asc");
        activityColumnExample.createCriteria().andStatusEqualTo(SysConfigConstants.STATUS_1);
        List<ActivityColumn> activityColumnList=activityColumnMapper.selectByExample(activityColumnExample);
        for(ActivityColumn activityColumn:activityColumnList){
            activityColumnMap.put(activityColumn.getId(),activityColumn.getTitle());
        }
        return activityColumnMap;
    }

    private String getActivityColumnName(String activityColumnIds,HashMap<Integer,String> activityColumnMap){
        String activityColumnName="";

        if(org.apache.commons.lang3.StringUtils.isNotBlank(activityColumnIds)) {
            try {
                String[] activityColumnIdArray = activityColumnIds.split(",");
                if (activityColumnIdArray != null && activityColumnIdArray.length > 0) {
                    for (int i = 0; i < activityColumnIdArray.length; i++) {
                        int columnId = Integer.parseInt(activityColumnIdArray[i]);
                        String columnName=activityColumnMap.get(columnId);
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(columnName)) {
                            if (org.apache.commons.lang3.StringUtils.isBlank(activityColumnName)) {
                                activityColumnName = columnName;
                            } else {
                                activityColumnName += "," + columnName;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error("解析活动栏目id错误", e);
            }
        }
        return activityColumnName;
    }

    @Override
    public AllNewStatisticsResponse getAllStatistics(NewStatisticsRequest newStatisticsRequest) {
        String channel=newStatisticsRequest.getChannel();
        Integer adminId= UserUtil.getAdminId();
        if (adminId.equals(adminIdjxy) && StringUtils.isBlank(channel)){
            channel = "jxy-tt";
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(newStatisticsRequest.getUserid()) && "csb001@lc.com".equals(newStatisticsRequest.getUserid()) && StringUtils.isBlank(channel)){
            channel = "qw-tt";
        }
        String dayStr=newStatisticsRequest.getDateStr();
        //日期区间
        String startDate=newStatisticsRequest.getStartDate();
        String endDate=newStatisticsRequest.getEndDate();
        String activityType=newStatisticsRequest.getActivityType();
        String productName=newStatisticsRequest.getProductName();
        String platform=newStatisticsRequest.getPlatform();
        String activityColumn=newStatisticsRequest.getActivityColumn();
        Assert.notNull(startDate,"请选择开始时间！");
//        if(org.apache.commons.lang3.StringUtils.isBlank(platform)){
//            platform="h5";
//        }
        String scene = newStatisticsRequest.getScene();
        String account = newStatisticsRequest.getAccount();
        if (StringUtils.isNotBlank(account) && "全部".equals(account)){
            account ="";
        }
        StringBuilder keyBuilder=new StringBuilder();
        keyBuilder.append(newStatisticsRequest.getUserid());
        keyBuilder.append(channel);
        keyBuilder.append(dayStr);
        keyBuilder.append(startDate);
        keyBuilder.append(endDate);
        keyBuilder.append(activityType);
        keyBuilder.append(productName);
        keyBuilder.append(platform);
        keyBuilder.append(activityColumn);
        keyBuilder.append(scene);
        keyBuilder.append(account);
        if (newStatisticsRequest.getIsCost()!=null && newStatisticsRequest.getIsCost().equals(1)) {
            keyBuilder.append(newStatisticsRequest.getIsCost());
        }

        String redisKey=RedisConstants.NEW_PRODUCT_STATISTIC+ MD5Util.MD5(keyBuilder.toString());
        // 从redis取出商品记录
        String redisData = redisService.get(redisKey);
        if (StringUtils.isNotEmpty(redisData)) {
            return JSONObject.parseObject(redisData, AllNewStatisticsResponse.class);
        }
        AllNewStatisticsResponse allNewStatisticsResponse = new AllNewStatisticsResponse();
        NewStatisticsResponse sumNewStatisticsResponse = new NewStatisticsResponse();
        List<NewStatisticsResponse> productStatisticsList = new ArrayList<>();
        Date startTime =CalendarUtil.getStartTime(new Date());
        Date endTime = CalendarUtil.getEndTime(startTime);
        if(StringUtils.isNotBlank(dayStr)) {
            if (StringUtils.isNotBlank(dayStr) && dayStr.length() == 10) {
                startTime =CalendarUtil.getStartTime(CalendarUtil.dateFormat(dayStr));
                endTime = CalendarUtil.getEndTime(startTime);
                startDate=dayStr;
                endDate=dayStr;
            } else {
                startDate = CalendarUtil.dateFormat(new Date());
                endDate = CalendarUtil.dateFormat(new Date());
            }
        }else{
            startTime =CalendarUtil.getStartTime(CalendarUtil.dateFormat(startDate));
            endTime = CalendarUtil.getEndTime(CalendarUtil.dateFormat(endDate));
        }
        //按活动类型查询
        HashMap<Integer,Product> productHashMap=new HashMap<>();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(newStatisticsRequest.getActivityType())) {
            ProductExample productExample = new ProductExample();
            productExample.createCriteria()
                    .andStatusEqualTo((byte) 1)
                    .andActivityTypeEqualTo(newStatisticsRequest.getActivityType());
            List<Product> productList = productMapper.selectByExample(productExample);
            for(Product product:productList){
                productHashMap.put(product.getId(),product);
            }
        }
        HashMap<Integer,String>  activityColumnMap = getActivityColumnMap();
        List<String> channelList=null;
        Criteria criteria = null;
        if(StringUtils.isNotBlank(channel)&&channel.contains(",")){//多个渠道号
            channelList=Arrays.asList(channel.split(","));
            criteria = this.commonCriteria(activityType,null,productName,platform,startDate,endDate,activityColumn,channelList,scene,account);
        }else if (StringUtils.isNotBlank(channel)&& ("jxy-tt".equals(channel) || "qw-tt".equals(channel))){
            //特殊账号特殊处理
            if (adminId.equals(adminIdjxy) ||  "csb001@lc.com".equals(newStatisticsRequest.getUserid())){
                List<Channel> list = channelDao.getChannels(channel);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(list)){
                    channelList = list.stream().map(x->x.getChannel()).collect(Collectors.toList());
                }
            }
            criteria = this.commonCriteria(activityType,null,productName,platform,startDate,endDate,activityColumn,channelList,scene,account);
        } else {
            criteria = this.commonCriteria(activityType,channel,productName,platform,startDate,endDate,activityColumn,null,scene,account);
        }

        List<ProductDataResponse> productDataResponseList = this.aggregateByProductId(criteria,startDate,endDate);
        Map totalUVMap=this.countByUuid(criteria,startDate,endDate);
        Integer totalUV=0;
        if(totalUVMap!=null){
            totalUV=Integer.parseInt(String.valueOf(totalUVMap.get("totalUV")));
        }

        List<NewOrderStatisticsResponse> newOrderStatisticsList=new ArrayList<>();
        if(StringUtils.isNotBlank(channel)&&channel.contains(",")) {//多个渠道号
            newOrderStatisticsList=orderStatisticsMapper.getNewOrderStatisticsList(null,platform,startTime,endTime, activityType,channelList,scene,account);
        } else if (StringUtils.isNotBlank(channel)&& ("jxy-tt".equals(channel) || "qw-tt".equals(channel))){
            //特殊账号特殊处理
            if (adminId.equals(adminIdjxy) ||  "csb001@lc.com".equals(newStatisticsRequest.getUserid())){
                List<Channel> list = channelDao.getChannels(channel);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(list)){
                    channelList = list.stream().map(x->x.getChannel()).collect(Collectors.toList());
                }
            }
            newOrderStatisticsList=orderStatisticsMapper.getNewOrderStatisticsList(null,platform,startTime,endTime, activityType,channelList,scene,account);
        }else{
            newOrderStatisticsList=orderStatisticsMapper.getNewOrderStatisticsList(channel,platform,startTime,endTime, activityType,channelList,scene,account);
        }
        Map<Integer,NewOrderStatisticsResponse> newOrderStatisticsMap=new HashMap<>();
        if(!CollectionUtils.isEmpty(newOrderStatisticsList)){
            for(NewOrderStatisticsResponse newOrderStatisticsResponse:newOrderStatisticsList){
                newOrderStatisticsMap.put(newOrderStatisticsResponse.getProductId(),newOrderStatisticsResponse);
            }
        }
        Integer totalOrderNum=0;
        Integer totalRealOrderNum=0;
        Integer totalPayOrderNum=0;
        BigDecimal totalPayAmount=BigDecimal.ZERO;
        BigDecimal totalCostAmount=BigDecimal.ZERO;
        BigDecimal totalWxCostAmount=BigDecimal.ZERO;
        BigDecimal totalAliCostAmount=BigDecimal.ZERO;

        Integer totalWxPayNum=0;
        Integer totalAliPayNum=0;
        BigDecimal totalWxPayAmount = BigDecimal.ZERO;
        BigDecimal totalAliPayAmount = BigDecimal.ZERO;
        BigDecimal customerAmount = BigDecimal.ZERO;
        //退款金额
        BigDecimal refundMoney = BigDecimal.ZERO;
        //退款订单数量
        Integer refundTotal = 0;
        Integer productCount=0;
        for (ProductDataResponse productDataResponse : productDataResponseList) {
            Integer productId = productDataResponse.getProductId();
            NewStatisticsResponse newStatisticsResponse = new NewStatisticsResponse();
            newStatisticsResponse.setId(productCount+1);
            NewOrderStatisticsResponse newOrderStatisticsResponse=newOrderStatisticsMap.get(productId);
            if(null==newOrderStatisticsResponse){
                newOrderStatisticsResponse=new NewOrderStatisticsResponse();
                newOrderStatisticsResponse.setCostPrice(BigDecimal.ZERO);
                newOrderStatisticsResponse.setProductPrice(BigDecimal.ZERO);
                newOrderStatisticsResponse.setTotalOrderNum(0);
                newOrderStatisticsResponse.setRealOrderNum(0);
                newOrderStatisticsResponse.setUnPayOrderNum(0);
                newOrderStatisticsResponse.setPayOrderNum(0);
                newOrderStatisticsResponse.setPayAmount(BigDecimal.ZERO);
                newOrderStatisticsResponse.setWxPayAmount(BigDecimal.ZERO);
                newOrderStatisticsResponse.setWxPayOrderNum(0);
                newOrderStatisticsResponse.setAliPayAmount(BigDecimal.ZERO);
                newOrderStatisticsResponse.setAliPayOrderNum(0);
                newOrderStatisticsResponse.setActivityColumnIds("");
                newOrderStatisticsResponse.setRefundTotal(0);
                newOrderStatisticsResponse.setRefundMoney(BigDecimal.ZERO);
                if(org.apache.commons.lang3.StringUtils.isNotBlank(newStatisticsRequest.getActivityType())) {
                    Product product=productHashMap.get(productId);
                    if(product!=null){
                        newOrderStatisticsResponse.setCostPrice(product.getCostPrice());
                        newOrderStatisticsResponse.setProductPrice(product.getPrice());
                        newOrderStatisticsResponse.setActivityColumnIds(product.getActivityColumnIds());
                    }
                }
                newOrderStatisticsResponse.setWxRefundMoney(BigDecimal.ZERO);
                newOrderStatisticsResponse.setAliRefundMoney(BigDecimal.ZERO);
            }
            // uv
            Integer uv = productDataResponse.getUv();
            // 商品成本
            BigDecimal costPrice = newOrderStatisticsResponse.getCostPrice();
            // 商品售价
            BigDecimal productPrice = newOrderStatisticsResponse.getProductPrice();
            // 订单数
            Integer orderNum = newOrderStatisticsResponse.getTotalOrderNum();
            totalOrderNum+=orderNum;
            // 实际订单数
            Integer realOrderNum = newOrderStatisticsResponse.getRealOrderNum();
            totalRealOrderNum+=realOrderNum;
            //未支付订单数
            Integer unPayOrderNum = newOrderStatisticsResponse.getUnPayOrderNum();
            // 支付订单数
            Integer payOrderNum = newOrderStatisticsResponse.getPayOrderNum();

            totalPayOrderNum+=payOrderNum;
            //支付金额
            BigDecimal payAmount = newOrderStatisticsResponse.getPayAmount();
            totalPayAmount=totalPayAmount.add(payAmount);
            //微信支付金额
            BigDecimal wxPayAmount = newOrderStatisticsResponse.getWxPayAmount();
            totalWxPayAmount=totalWxPayAmount.add(wxPayAmount);
            //微信支付数
            Integer wxPayOrderNum = newOrderStatisticsResponse.getWxPayOrderNum();
            totalWxPayNum+=wxPayOrderNum;
            //支付宝支付金额
            BigDecimal aliPayAmount = newOrderStatisticsResponse.getAliPayAmount();
            totalAliPayAmount=totalAliPayAmount.add(aliPayAmount);
            //支付宝支付数
            Integer aliPayOrderNum = newOrderStatisticsResponse.getAliPayOrderNum();
            totalAliPayNum+=aliPayOrderNum;
            //在线成本(商品成本*(支付订单数-退款订单数))
            BigDecimal costAmount = Optional.ofNullable(newOrderStatisticsResponse.getOnlineCostPrice()).orElse(BigDecimal.ZERO);
            //在线微信成本（商品成本*(微信支付订单数-微信退款订单数量)）
            BigDecimal wxCostAmount = Optional.ofNullable(newOrderStatisticsResponse.getOnlineWxPayCostPrice()).orElse(BigDecimal.ZERO);
            //在线支付宝成本（商品成本*(微信支付订单数-支付宝退款订单数量)）
            BigDecimal aliCostAmount = Optional.ofNullable(newOrderStatisticsResponse.getOnlineAliPayCostPrice()).orElse(BigDecimal.ZERO);
            if (newStatisticsRequest.getIsCost()!=null && newStatisticsRequest.getIsCost().equals(1)) {
                String key = "random-channel:" + newOrderStatisticsResponse.getChannel();
                String channelRandom = redisService.get(key);
                double random ;
                if (StringUtils.isBlank(channelRandom)) {
                    random = ThreadLocalRandom.current().nextDouble(0.495, 0.505);
                    redisService.set(key,String.valueOf(random));
                } else {
                    random = Double.valueOf(channelRandom);
                }

                costAmount = payAmount.subtract(newOrderStatisticsResponse.getRefundMoney()).multiply(new BigDecimal(random)).setScale(0,BigDecimal.ROUND_DOWN);
                wxCostAmount = wxPayAmount.subtract(newOrderStatisticsResponse.getWxRefundMoney()).multiply(new BigDecimal(random)).setScale(0,BigDecimal.ROUND_DOWN);
                aliCostAmount = aliPayAmount.subtract(newOrderStatisticsResponse.getAliRefundMoney()).multiply(new BigDecimal(random)).setScale(0,BigDecimal.ROUND_DOWN);;
            }
            totalCostAmount=totalCostAmount.add(costAmount);
            totalWxCostAmount=totalWxCostAmount.add(wxCostAmount);
            totalAliCostAmount=totalAliCostAmount.add(aliCostAmount);

            // 订单率 实际订单数/商品uv
            BigDecimal orderRatio = uv == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(realOrderNum)
                    .divide(BigDecimal.valueOf(uv), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            // 支付率 （支付订单/实际订单数）
            BigDecimal payRatio = realOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(payOrderNum)
                    .divide(BigDecimal.valueOf(realOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);

            // 微信支付率 （微信支付订单/支付订单数）
            BigDecimal wxPayRatio = payOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(wxPayOrderNum)
                    .divide(BigDecimal.valueOf(payOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);

            // 支付宝支付率 （支付宝支付订单/支付订单数）
            BigDecimal aliPayRatio = payOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(aliPayOrderNum)
                    .divide(BigDecimal.valueOf(payOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            //客单 (支付金额/支付订单数)
            BigDecimal customerPrice= payOrderNum ==0 ? BigDecimal.ZERO : payAmount.divide(BigDecimal.valueOf(payOrderNum), 2, RoundingMode.HALF_UP);
            //商品退款数
            Integer productRefundTotal = newOrderStatisticsResponse.getRefundTotal();
            //商品退款金额
            BigDecimal productRefundMoney = newOrderStatisticsResponse.getRefundMoney();
            // 商品退款率 （退款订单数/支付订单数）
//            BigDecimal productRefundRatio = productRefundTotal == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(productRefundTotal)
//                    .divide(BigDecimal.valueOf(payOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            BigDecimal productRefundRatio = BigDecimal.ZERO;
            if(productRefundMoney !=null && newOrderStatisticsResponse.getPayAmount() !=null && newOrderStatisticsResponse.getPayAmount().compareTo(BigDecimal.ZERO) !=0) {
                productRefundRatio = productRefundMoney.divide(newOrderStatisticsResponse.getPayAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            }
            //累加退款订单数
            refundTotal += newOrderStatisticsResponse.getRefundTotal();
            //累加退款金额
            refundMoney = refundMoney.add(newOrderStatisticsResponse.getRefundMoney());

            newStatisticsResponse.setProductId(productId);
            newStatisticsResponse.setActivityType(ActivityTypeNameCode.getName(productDataResponse.getActivityType()));
            newStatisticsResponse.setProductName(productDataResponse.getProductName());
            newStatisticsResponse.setUv(productDataResponse.getUv());
            newStatisticsResponse.setCostPrice(costPrice);
            newStatisticsResponse.setPrice(productPrice);
            newStatisticsResponse.setTotalOrderNum(orderNum);
            newStatisticsResponse.setOrderNum(realOrderNum);
            newStatisticsResponse.setOrderRatio(orderRatio);
            newStatisticsResponse.setPayOrderNum(payOrderNum);
            newStatisticsResponse.setOnlineCostPrice(costAmount);
            newStatisticsResponse.setOnlineWxPayCostPrice(wxCostAmount);
            newStatisticsResponse.setOnlineAliPayCostPrice(aliCostAmount);
            newStatisticsResponse.setOnlinePrice(payAmount);
            newStatisticsResponse.setOnlinePayRatio(payRatio);
            newStatisticsResponse.setWxPayNum(wxPayOrderNum);
            newStatisticsResponse.setWxPrice(wxPayAmount);
            newStatisticsResponse.setWxPayRatio(wxPayRatio);
            newStatisticsResponse.setAlipayPayNum(aliPayOrderNum);
            newStatisticsResponse.setAlipayPrice(aliPayAmount);
            newStatisticsResponse.setAlipayPayRatio(aliPayRatio);
            newStatisticsResponse.setCustomPrice(customerPrice);
            newStatisticsResponse.setActivityColumns(getActivityColumnName(newOrderStatisticsResponse.getActivityColumnIds(),activityColumnMap));
            newStatisticsResponse.setRefundTotal(productRefundTotal);
            newStatisticsResponse.setRefundMoney(productRefundMoney);
            newStatisticsResponse.setRefundRatio(productRefundRatio);
            productStatisticsList.add(newStatisticsResponse);
            productCount++;
        }
        productStatisticsList=productStatisticsList.stream().sorted(Comparator.comparing(NewStatisticsResponse::getOrderNum).reversed()).collect(Collectors.toList());
        //订单率 （商品订单数/总订单数）
        for (int i=0;i<productStatisticsList.size();i++) {
            productStatisticsList.get(i).setId(i+1);
            BigDecimal orderProportion = totalRealOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(productStatisticsList.get(i).getOrderNum())
                    .divide(BigDecimal.valueOf(totalRealOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
            //订单占比
            productStatisticsList.get(i).setOrderProportion(orderProportion);
            BigDecimal roi=productStatisticsList.get(i).getOnlinePrice().subtract(productStatisticsList.get(i).getOnlineCostPrice()).subtract(productStatisticsList.get(i).getRefundMoney())
                    .divide(BigDecimal.valueOf(productStatisticsList.get(i).getUv()),2,BigDecimal.ROUND_HALF_UP);

            productStatisticsList.get(i).setRoi(roi);
            if(totalUV>0){
                BigDecimal uvRatio=BigDecimal.valueOf(productStatisticsList.get(i).getUv()).divide(BigDecimal.valueOf(totalUV),4,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                productStatisticsList.get(i).setUvRatio(uvRatio);
            }else{
                productStatisticsList.get(i).setUvRatio(BigDecimal.ZERO);
            }
        }
        //查询活跃用户
        DataStatisticsRequest dataStatisticsRequest = new DataStatisticsRequest();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime startLocal = LocalDateTime.of(LocalDate.parse(startDate, df), LocalDateTime.MIN.toLocalTime());
        LocalDateTime endLocal = LocalDateTime.of(LocalDate.parse(endDate, df), LocalDateTime.MIN.toLocalTime());
        dataStatisticsRequest.setStartTime(startLocal);
        dataStatisticsRequest.setEndTime(endLocal);
//        Integer daus = platformStatisticService.getUv(dataStatisticsRequest);
        //商品数
        sumNewStatisticsResponse.setProductName(String.valueOf(productCount));
        //总UV
        sumNewStatisticsResponse.setUv(totalUV);
        sumNewStatisticsResponse.setTotalOrderNum(totalOrderNum);
        sumNewStatisticsResponse.setOrderNum(totalRealOrderNum);
        sumNewStatisticsResponse.setPayOrderNum(totalPayOrderNum);
        // 订单率 实际订单数/商品uv
        BigDecimal totalOrderRatio = totalUV == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(totalRealOrderNum)
                .divide(BigDecimal.valueOf(totalUV), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
        // 支付率 （支付订单/实际订单数）
        BigDecimal totalPayRatio = totalRealOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(totalPayOrderNum)
                .divide(BigDecimal.valueOf(totalRealOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);

        // 微信支付率 （微信支付订单/支付订单数）
        BigDecimal totalWxPayRatio = totalPayOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(totalWxPayNum)
                .divide(BigDecimal.valueOf(totalPayOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);

        // 支付宝支付率 （支付宝支付订单/支付订单数）
        BigDecimal totalAliPayRatio = totalPayOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(totalAliPayNum)
                .divide(BigDecimal.valueOf(totalPayOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
        //客单 (总支付金额/总支付订单数)
        customerAmount= totalPayOrderNum ==0 ? BigDecimal.ZERO : totalPayAmount.divide(BigDecimal.valueOf(totalPayOrderNum), 2, RoundingMode.HALF_UP);
        sumNewStatisticsResponse.setOrderRatio(totalOrderRatio);
        sumNewStatisticsResponse.setOnlineCostPrice(totalCostAmount);
        sumNewStatisticsResponse.setOnlineWxPayCostPrice(totalWxCostAmount);
        sumNewStatisticsResponse.setOnlineAliPayCostPrice(totalAliCostAmount);

        sumNewStatisticsResponse.setOnlinePrice(totalPayAmount);
        sumNewStatisticsResponse.setOnlinePayRatio(totalPayRatio);
        sumNewStatisticsResponse.setWxPrice(totalWxPayAmount);
        sumNewStatisticsResponse.setWxPayNum(totalWxPayNum);
        sumNewStatisticsResponse.setWxPayRatio(totalWxPayRatio);
        sumNewStatisticsResponse.setAlipayPayNum(totalAliPayNum);
        sumNewStatisticsResponse.setAlipayPrice(totalAliPayAmount);
        sumNewStatisticsResponse.setAlipayPayRatio(totalAliPayRatio);
        sumNewStatisticsResponse.setCustomPrice(customerAmount);
        sumNewStatisticsResponse.setRefundTotal(refundTotal);
        sumNewStatisticsResponse.setRefundMoney(refundMoney);
//        sumNewStatisticsResponse.setDaus(daus.longValue());
        // 退款率 （退款订单数/支付订单数）
//        BigDecimal refundRatio = refundTotal == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(refundTotal)
//                .divide(BigDecimal.valueOf(totalPayOrderNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
        //退款率：退款金额/在线金额
        BigDecimal refundRatio = BigDecimal.ZERO;
        if (refundMoney !=null && totalPayAmount!= null && totalPayAmount.compareTo(BigDecimal.ZERO) !=0) {
            refundRatio = refundMoney.divide(totalPayAmount, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
        }

        sumNewStatisticsResponse.setRefundRatio(refundRatio);
        ProductExample productExample = new ProductExample();
        ProductExample.Criteria criteria1 = productExample.createCriteria().andStatusEqualTo((byte) 1);
        if (StringUtils.isNotEmpty(platform)) {
            criteria1.andPlatformDataEqualTo(platform);
        }
        long total = productMapper.countByExample(productExample);
        sumNewStatisticsResponse.setProductTotal(total);
        //特殊账号特殊处理
        if (!adminId.equals(adminIdjxy)){
            allNewStatisticsResponse.setNewStatisticsResponseList(productStatisticsList);
        }

        if(newStatisticsRequest.isShowTotal()) {
            allNewStatisticsResponse.setSumNewStatisticsResponse(sumNewStatisticsResponse);
        }
        //放入redis
        redisService.set(redisKey, JSONObject.toJSONString(allNewStatisticsResponse));
        redisService.expire(redisKey,120);
        return allNewStatisticsResponse;
    }

    /**
     * 通用查询
     * @param channel
     * @return
     */
    public Criteria commonCriteria(String activityType,String channel,String productName,String platform,String startDate,String endDate,String activityColumn,List<String> channelList,String scene,String account) {
        Criteria criteria = Criteria.where("dayTime").gte(startDate).lte(endDate);
        if (StringUtils.isNotEmpty(activityType)) {
            criteria.and("activityType").is(activityType);
        }
        if (StringUtils.isNotEmpty(channel)) {
            criteria.and("channel").is(channel);
        }
        if(channelList!=null&&channelList.size()>0){
            criteria.and("channel").in(channelList);
        }
        if (StringUtils.isNotEmpty(productName)) {
            criteria.and("productName").is(productName);
        }
        if (StringUtils.isNotEmpty(scene)) {
            criteria.and("scene").is(scene);
        }
        if (StringUtils.isNotEmpty(platform)) {
            criteria.and("platform").is(platform);
        }
        if (StringUtils.isNotBlank(account)){
            criteria.and("account").is(account);
        }
        if (StringUtils.isNotEmpty(activityColumn)) {
            Criteria cr = new Criteria();
            String[] activityColumnIdArray = activityColumn.split(",");
            if (activityColumnIdArray != null && activityColumnIdArray.length > 0) {
                Criteria activityColumnCri=Criteria.where("activityColumnIds");
                for(String activityColumnId:activityColumnIdArray){
                    activityColumnCri.regex(Pattern.compile("^.*" +activityColumnId + ".*$", Pattern.CASE_INSENSITIVE));
                }
                cr.andOperator(activityColumnCri);
            }
            criteria.andOperator(cr);
        }
        log.info(criteria.toString());
        return criteria;
    }
    public Map countByUuid(Criteria criteria,String startDate,String endDate){
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("uuid"),
                Aggregation.count().as("totalUV")
        ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
        //如果起始时间和截止时间为同一天，则查询日集合
        if(StringUtils.isNotBlank(startDate)&&startDate.equals(endDate)){
            return mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT+startDate, Map.class).getUniqueMappedResult();
        }else {
            return mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT_STATISTICS, Map.class).getUniqueMappedResult();
        }
    }
    public List<ProductDataResponse> aggregateByProductId(Criteria criteria,String startDate,String endDate) {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("productId", "uuid")
                        .last("productId").as("productId")
                        .last("productName").as("productName")
                        .last("scene").as("scene")
                        .last("account").as("account")
                        .last("activityType").as("activityType"),
                Aggregation.group("productId").count().as("uv")
                        .last("productName").as("productName")
                        .last("productId").as("productId")
                        .last("scene").as("scene")
                        .last("account").as("account")
                        .last("activityType").as("activityType")
        ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
        //如果起始时间和截止时间为同一天，则查询日集合
        if(StringUtils.isNotBlank(startDate)&&startDate.equals(endDate)){
            return mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT+startDate, ProductDataResponse.class)
                    .getMappedResults();
        }else {
            return mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT_STATISTICS, ProductDataResponse.class)
                    .getMappedResults();
        }
    }

    @Override
    public Map<String, Object> getPayNumForUserStatistics(String startTime, String endTime) {
        LocalDate startDate = LocalDate.parse(startTime);
        LocalDate endDate = LocalDate.parse(endTime);
        List<LocalDate> datesBetween = DateUtils.getDatesBetween(startDate, endDate);
        CountDownLatch countDownLatch = new CountDownLatch(datesBetween.size());
        List<UserPayStatisticsResponse> collect = new ArrayList<>();
        datesBetween.stream().forEach(e->{
            new Thread(() -> {
                try {
                    List<UserPayStatisticsResponse> payNumForUser = orderStatisticsMapper.getPayNumForUser(e + " 00:00:00", e.plusDays(1) + " 00:00:00");
                    UserPayStatisticsResponse response = new UserPayStatisticsResponse();
                    UserPayStatisticsResponse nowEntity = payNumForUser.get(0);
                    BeanUtils.copyProperties(nowEntity, response);
                    response.setDate(e.toString());
                    response.setTotal(nowEntity.getOne() + nowEntity.getTwo() + nowEntity.getThree());
                    if(response.getTotal() != 0){
                        response.setOneRate(new BigDecimal(response.getOne()).divide(new BigDecimal(response.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                        response.setTwoRate(new BigDecimal(response.getTwo()).divide(new BigDecimal(response.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                        response.setThreeRate(new BigDecimal(response.getThree()).divide(new BigDecimal(response.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                    }
                    collect.add(response);
                } catch (Exception exc) {
                    log.error("统计出错！{}", exc);
                } finally {
                    countDownLatch.countDown();
                }
            }).start();
        });
        try {
            countDownLatch.await();
        } catch (Exception e) {
            log.error("===统计下单人数出错==={}", e);
        }
        //按日期排序
        List<UserPayStatisticsResponse> detail = collect.stream().sorted(Comparator.comparing(UserPayStatisticsResponse::getDate,Comparator.reverseOrder())).collect(Collectors.toList());
        UserPayStatisticsResponse totalRespone = new UserPayStatisticsResponse();
        //统计汇总
        for (UserPayStatisticsResponse response : detail) {
            totalRespone.setOne(Optional.ofNullable(totalRespone.getOne()).orElse(0) + response.getOne());
            totalRespone.setTwo(Optional.ofNullable(totalRespone.getTwo()).orElse(0) + response.getTwo());
            totalRespone.setThree(Optional.ofNullable(totalRespone.getThree()).orElse(0) + response.getThree());
            totalRespone.setTotal(Optional.ofNullable(totalRespone.getTotal()).orElse(0) + response.getTotal());
        }
        //汇总统计占比
        if(totalRespone.getTotal() != null){
            totalRespone.setOneRate(new BigDecimal(totalRespone.getOne()).divide(new BigDecimal(totalRespone.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            totalRespone.setTwoRate(new BigDecimal(totalRespone.getTwo()).divide(new BigDecimal(totalRespone.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            totalRespone.setThreeRate(new BigDecimal(totalRespone.getThree()).divide(new BigDecimal(totalRespone.getTotal()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
        }
        Map<String, Object> rateResult = new HashMap<>();
        rateResult.put("total",totalRespone);
        rateResult.put("detail",detail);
        return rateResult;
    }


    /**
     * 用户偏好统计
     */
    @Override
    public List<UserOrderAnalysisResponse> getUserAnalysis(UserStatisticsRequest userStatisticsRequest) {
        Integer tabType = userStatisticsRequest.getTabType();
        List<UserOrderAnalysisResponse> result = new ArrayList<>();
        String key = userStatisticsRequest.toString();
        String value = redisService.get(key);
        if(StringUtils.isEmpty(value)){
            switch (tabType){
                case 1:
                    result = userPageViewPreference(userStatisticsRequest);
                    break;
                case 2:
                    result = userOrdersPreference(userStatisticsRequest);
                    break;
                case 3:
                    result = userRepurchasePreference(userStatisticsRequest);
                    break;
                default:
                    result = new ArrayList<>();
            }
            redisService.set(key, JSON.toJSONString(result), 5 * 60);
        }else {
            result = JSONArray.parseArray(value, UserOrderAnalysisResponse.class);
        }
        return result;
    }

    @Override
    public List<NewStatisticsResponse> getFinancialExport(NewStatisticsRequest newStatisticsRequest) {
        String startDate=newStatisticsRequest.getStartDate();
        String endDate=newStatisticsRequest.getEndDate();
        Assert.notNull(startDate,"请选择开始时间！");
        Assert.notNull(endDate,"请选择结束时间！");


        Date startTime =CalendarUtil.getStartTime(CalendarUtil.dateFormat(startDate));
        Date endTime = CalendarUtil.getEndTime(CalendarUtil.dateFormat(endDate));
        List<NewStatisticsResponse> list = orderStatisticsMapper.getFinancialExport(startTime,endTime,newStatisticsRequest.getPromotionChannel());
        return list;
    }


    /**
     * 用户访问偏好
     */
    public List<UserOrderAnalysisResponse> userPageViewPreference(UserStatisticsRequest userStatisticsRequest){
        Integer type = userStatisticsRequest.getType();
        List<UserOrderAnalysisResponse> result = new ArrayList<>();
        String channel = userStatisticsRequest.getChannel();
        //日期区间
        String startDate = userStatisticsRequest.getStartDate();
        String endDate = userStatisticsRequest.getEndDate();
        String platform = userStatisticsRequest.getPlatform();
        String scene = userStatisticsRequest.getScene();
        String account = userStatisticsRequest.getAccount();
        Criteria criteria = null;
        if (StringUtils.isNotBlank(channel) && channel.contains(",")) {//多个渠道号
            List<String> channelList = Arrays.asList(channel.split(","));
            criteria = this.commonCriteria(null, null, null, platform, startDate, endDate, null, channelList, scene, account);
        } else {
            criteria = this.commonCriteria(null, channel, null, platform, startDate, endDate, null, null, scene, account);
        }
        //根据省份统计
        if(type == 1){
            Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.group("ip", "uuid")
                            .last("ip").as("provinceName")
                            .last("uuid").as("percentage")
            ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
            List<UserOrderAnalysisResponse> list = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT_STATISTICS, UserOrderAnalysisResponse.class)
                    .getMappedResults();
            //地址库方式
            if (org.apache.commons.lang3.StringUtils.isEmpty(ipSourceFilePath)) {
                ipSourceFilePath = "/mnt/ipsourcefile/qqzeng-ip-utf8.dat";
            }
            IpSearch finder = IpSearch.getInstance(ipSourceFilePath);
            // 使用 Map 进行计数
            ConcurrentHashMap<String, Integer> provinceCountMap = new ConcurrentHashMap<>();
            list.parallelStream().forEach(e -> {
                //防止数据中存在不正确的ip
                if(!e.getProvinceName().matches("[0-9.]+")){
                    return;
                }
                String ip = finder.Get(e.getProvinceName());
                Map<String, String> hashMap = IpSearch.analysisResult(ip);
                String province = hashMap.get("province") == null || hashMap.get("province") == "" ? "未知" : hashMap.get("province");
                provinceCountMap.merge(province, 1, Integer::sum);
            });
            double total = 0;
            // 打印统计结果
            for (Map.Entry<String, Integer> entry : provinceCountMap.entrySet()) {
                total += entry.getValue();
            }
            for (Map.Entry<String, Integer> entry : provinceCountMap.entrySet()) {
                UserOrderAnalysisResponse response = new UserOrderAnalysisResponse();
                response.setProvinceName(entry.getKey());
                response.setTotalUser(entry.getValue());
                response.setPercentage(String.valueOf(total == 0 ? 0 : entry.getValue()/total));
                result.add(response);
            }
        } else if (type == 2) {//根据商品分类统计
            Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.group("productId", "uuid"),
                    Aggregation.group("productId").count().as("totalUser").last("productId").as("categoryName")
            ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
            List<UserOrderAnalysisResponse> list = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PRODUCT_STATISTICS, UserOrderAnalysisResponse.class)
                    .getMappedResults();
            if(CollectionUtils.isEmpty(list)){
                return result;
            }
            List<String> ids = list.stream().map(UserOrderAnalysisResponse::getCategoryName).collect(Collectors.toList());
            List<Product> products = productMapper.getProductTopCategory(ids);
            Map<Integer, String> productTopCategory = products.stream().collect(Collectors.toMap(map -> map.getId(), map -> map.getTopCategoryTitle()));
            // 使用 Map 进行计数
            ConcurrentHashMap<String, Integer> provinceCountMap = new ConcurrentHashMap<>();
            list.parallelStream().forEach(e -> {
                String topCategory = productTopCategory.get(Integer.valueOf(e.getCategoryName()));
                topCategory = StringUtils.isEmpty(topCategory) ? "未知分类" : topCategory;
                provinceCountMap.merge(topCategory, 1, Integer::sum);
            });
            double total = 0;
            // 打印统计结果
            for (Map.Entry<String, Integer> entry : provinceCountMap.entrySet()) {
                total += entry.getValue();
            }
            for (Map.Entry<String, Integer> entry : provinceCountMap.entrySet()) {
                UserOrderAnalysisResponse response = new UserOrderAnalysisResponse();
                response.setCategoryName(entry.getKey());
                response.setTotalUser(entry.getValue());
                response.setPercentage(String.valueOf(total == 0 ? 0 : entry.getValue()/total));
                result.add(response);
            }
        }
        result = result.stream().sorted(Comparator.comparing(UserOrderAnalysisResponse::getTotalUser).reversed()).collect(Collectors.toList());
        result.stream().forEach(e->{
            BigDecimal per = new BigDecimal(e.getPercentage()).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
            e.setPercentage(per.toPlainString());
        });
        return result;
    }

    /**
     * 用户下单偏好
     */
    public List<UserOrderAnalysisResponse> userOrdersPreference(UserStatisticsRequest userStatisticsRequest){
        List<UserOrderAnalysisResponse> orderStatisticsByProvince = new ArrayList<>();
        String channel = userStatisticsRequest.getChannel();
        List<String> channels = new ArrayList<>();
        if(StringUtils.isNotEmpty(channel)){
            channels = Arrays.asList(channel.split(","));
        }
        Integer type = userStatisticsRequest.getType();
        //按省份统计
        if(type == 1){
            orderStatisticsByProvince = orderStatisticsMapper.getOrderStatisticsByProvince(userStatisticsRequest,channels);
        }else if(type == 2){//按商品类目统计
            orderStatisticsByProvince = orderStatisticsMapper.getOrderStatisticsByCategory(userStatisticsRequest,channels);
        }else if(type == 3){//按客单价统计

            List<UserOrderAnalysisResponse> one = orderStatisticsMapper.getOrderStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(10), new BigDecimal(50));
            List<UserOrderAnalysisResponse> two = orderStatisticsMapper.getOrderStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(51), new BigDecimal(100));
            List<UserOrderAnalysisResponse> three = orderStatisticsMapper.getOrderStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(101), new BigDecimal(200));
            List<UserOrderAnalysisResponse> four = orderStatisticsMapper.getOrderStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(201), new BigDecimal(300));
            List<UserOrderAnalysisResponse> five = orderStatisticsMapper.getOrderStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(301), null);
            orderStatisticsByProvince = dealProductPrice(one, two, three, four, five);
        }
        orderStatisticsByProvince = orderStatisticsByProvince.stream().sorted(Comparator.comparing(UserOrderAnalysisResponse::getTotalUser).reversed()).collect(Collectors.toList());
        orderStatisticsByProvince.stream().forEach(e->{
            BigDecimal per = new BigDecimal(e.getPercentage()).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
            e.setPercentage(per.toPlainString());
        });
        return orderStatisticsByProvince;

    }

    /**
     * 用户复购偏好
     */
    public List<UserOrderAnalysisResponse> userRepurchasePreference(UserStatisticsRequest userStatisticsRequest){
        List<UserOrderAnalysisResponse> orderStatisticsByProvince = new ArrayList<>();
        String channel = userStatisticsRequest.getChannel();
        List<String> channels = new ArrayList<>();
        if(StringUtils.isNotEmpty(channel)){
            channels = Arrays.asList(channel.split(","));
        }
        Integer type = userStatisticsRequest.getType();
        if(type == 1){
            orderStatisticsByProvince = orderStatisticsMapper.getRepurchaseStatisticsByProvince(userStatisticsRequest,channels);
        }else if(type == 2){
            orderStatisticsByProvince = orderStatisticsMapper.getRepurchaseStatisticsByCategory(userStatisticsRequest,channels);
        }else if(type == 3){
            List<UserOrderAnalysisResponse> one = orderStatisticsMapper.getRepurchaseStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(10), new BigDecimal(50));
            List<UserOrderAnalysisResponse> two = orderStatisticsMapper.getRepurchaseStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(51), new BigDecimal(100));
            List<UserOrderAnalysisResponse> three = orderStatisticsMapper.getRepurchaseStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(101), new BigDecimal(200));
            List<UserOrderAnalysisResponse> four = orderStatisticsMapper.getRepurchaseStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(201), new BigDecimal(300));
            List<UserOrderAnalysisResponse> five = orderStatisticsMapper.getRepurchaseStatisticsByPrice(userStatisticsRequest, channels, new BigDecimal(301), null);
            orderStatisticsByProvince = dealProductPrice(one, two, three, four, five);
        }
        orderStatisticsByProvince.stream().forEach(e->{
            BigDecimal per = new BigDecimal(e.getPercentage()).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
            e.setPercentage(per.toPlainString());
        });
        return orderStatisticsByProvince;
    }

    public List<UserOrderAnalysisResponse> dealProductPrice(List<UserOrderAnalysisResponse> one,List<UserOrderAnalysisResponse> two,
                                 List<UserOrderAnalysisResponse> three,List<UserOrderAnalysisResponse> four,List<UserOrderAnalysisResponse> five){
        List<UserOrderAnalysisResponse> orderStatisticsByProvince = new ArrayList<>();
        double total = one.size() + two.size() + three.size() + four.size() + five.size();
        UserOrderAnalysisResponse oneResponse = new UserOrderAnalysisResponse();
        oneResponse.setAvo("[10,50]");
        oneResponse.setTotalUser(one.size());
        oneResponse.setPercentage(total == 0 ? "0" : String.valueOf(one.size() / total));
        orderStatisticsByProvince.add(oneResponse);

        UserOrderAnalysisResponse twoResponse = new UserOrderAnalysisResponse();
        twoResponse.setAvo("[51,100]");
        twoResponse.setTotalUser(two.size());
        twoResponse.setPercentage(total == 0 ? "0" : String.valueOf(two.size()/total));
        orderStatisticsByProvince.add(twoResponse);

        UserOrderAnalysisResponse threeResponse = new UserOrderAnalysisResponse();
        threeResponse.setAvo("[101,200]");
        threeResponse.setTotalUser(three.size());
        threeResponse.setPercentage(total == 0 ? "0" : String.valueOf(three.size()/total));
        orderStatisticsByProvince.add(threeResponse);

        UserOrderAnalysisResponse fourResponse = new UserOrderAnalysisResponse();
        fourResponse.setAvo("[201,300]");
        fourResponse.setTotalUser(four.size());
        fourResponse.setPercentage(total == 0 ? "0" : String.valueOf(four.size()/total));
        orderStatisticsByProvince.add(fourResponse);

        UserOrderAnalysisResponse fiveResponse = new UserOrderAnalysisResponse();
        fiveResponse.setAvo("[300+]");
        fiveResponse.setTotalUser(five.size());
        fiveResponse.setPercentage(total == 0 ? "0" : String.valueOf(five.size()/total));
        orderStatisticsByProvince.add(fiveResponse);
        return orderStatisticsByProvince;
    }

    public static void main(String[] args) {
        String str = "240e:45b:7e8d:df8f::1";
        boolean matches = str.matches("[0-9.]+");
        System.out.println(matches);
    }
}